home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / euphor14.zip / ALLSORTS.EX next >
Text File  |  1996-05-20  |  8KB  |  376 lines

  1.         ----------------------------------------
  2.         -- Sorting Algorithms in Euphoria     --
  3.         -- These routines will sort sequences --
  4.         -- of general Euphoria objects        --
  5.         ----------------------------------------
  6. without type_check
  7.  
  8. constant MAX = 4800
  9. constant TRUE = 1, FALSE = 0
  10. constant CHECK_RESULTS = FALSE
  11.  
  12. integer hybrid_limit
  13.  
  14. type natural(integer x)
  15.     return x >= 0
  16. end type
  17.  
  18. type file_number(integer x)
  19.     return x >= -1
  20. end type
  21.  
  22. function simple_sort(sequence x)
  23. -- put x into ascending order
  24. -- using a very simple sort
  25. object temp
  26.  
  27.     for i = 1 to length(x) - 1 do
  28.     for j = i + 1 to length(x) do
  29.         if compare(x[j],x[i]) < 0 then
  30.         temp = x[j]
  31.         x[j] = x[i]
  32.         x[i] = temp
  33.         end if
  34.     end for
  35.     end for
  36.     return x
  37. end function
  38.  
  39.  
  40. function bubble_sort(sequence x)
  41. -- put x into ascending order
  42. -- using bubble sort
  43. object temp
  44. natural flip, limit
  45.  
  46.     flip = length(x)
  47.     while flip > 0 do
  48.     limit = flip
  49.     flip = 0
  50.     for i = 1 to limit - 1 do
  51.         if compare(x[i+1], x[i]) < 0 then
  52.         temp = x[i+1]
  53.         x[i+1] = x[i]
  54.         x[i] = temp
  55.         flip = i
  56.         end if
  57.     end for
  58.     end while
  59.     return x
  60. end function
  61.  
  62. function insertion_sort(sequence x)
  63. -- put x into ascending order
  64. -- using insertion sort
  65. object temp
  66. natural final
  67.  
  68.     for i = 2 to length(x) do
  69.     temp = x[i]
  70.     final = 1
  71.     for j = i-1 to 1 by -1 do
  72.         if compare(temp, x[j]) < 0 then
  73.         x[j+1] = x[j]
  74.         else
  75.         final = j + 1
  76.         exit
  77.         end if
  78.     end for
  79.     x[final] = temp
  80.     end for
  81.     return x
  82. end function
  83.  
  84. function shell_sort(sequence x)
  85. -- Shell sort based on insertion sort
  86.  
  87.     integer gap, j, first, last
  88.     object tempi, tempj
  89.  
  90.     last = length(x)
  91.     gap = floor(last / 3) + 1
  92.     while TRUE do
  93.     first = gap + 1
  94.     for i = first to last do
  95.         tempi = x[i]
  96.         j = i - gap
  97.         while TRUE do
  98.         tempj = x[j]
  99.         if compare(tempi, tempj) >= 0 then
  100.             j = j + gap
  101.             exit
  102.         end if
  103.         x[j+gap] = tempj
  104.         if j <= gap then
  105.             exit
  106.         end if
  107.         j = j - gap
  108.         end while
  109.         x[j] = tempi
  110.     end for
  111.     if gap = 1 then
  112.         return x
  113.     else
  114.         gap = floor(gap / 3) + 1
  115.     end if
  116.     end while
  117. end function
  118.  
  119.  
  120. global function quick_sort(sequence x)
  121. -- put x into ascending order
  122. -- using recursive quick sort
  123.     natural n, last
  124.     object temp, midval
  125.  
  126.     n = length(x)
  127.     if n < 2 then
  128.     return x -- already sorted (trivial case)
  129.     end if
  130.  
  131.     midval = x[(n + 1) / 2]
  132.     x[(n + 1) / 2] = x[1]
  133.  
  134.     last = 1
  135.     for i = 2 to n do
  136.     if compare(x[i], midval) < 0 then
  137.         last = last + 1
  138.         temp = x[last]  x[last] = x[i]  x[i] = temp
  139.     end if
  140.     end for
  141.  
  142.     return quick_sort(x[2..last]) & {midval} & quick_sort(x[last+1..n])
  143. end function
  144.  
  145.  
  146. global function hybrid_sort(sequence x)
  147. -- put x into ascending order
  148. -- using recursive quick sort
  149. -- but call insertion sort for short sequences
  150.     natural n, last, midpt
  151.     object midval, temp
  152.  
  153.     n = length(x)
  154.     if n < hybrid_limit then
  155.     return insertion_sort(x)
  156.     end if
  157.  
  158.     midpt = floor((n + 1) / 2)
  159.     midval = x[midpt]
  160.     x[midpt] = x[1]
  161.  
  162.     last = 1
  163.     for i = 2 to n do
  164.     if compare(x[i], midval) < 0 then
  165.         last = last + 1
  166.         temp = x[last]  x[last] = x[i]  x[i] = temp
  167.     end if
  168.     end for
  169.  
  170.     return hybrid_sort(x[2..last]) & {midval} & hybrid_sort(x[last+1..n])
  171. end function
  172.  
  173. sequence x
  174.  
  175. procedure g_insertion_sort()
  176. -- put global variable x into ascending order
  177. -- using insertion sort of general objects
  178. object temp
  179. natural final
  180.  
  181.     for i = 2 to length(x) do
  182.     temp = x[i]
  183.     final = 1
  184.     for j = i-1 to 1 by -1 do
  185.         if compare(temp, x[j]) < 0 then
  186.         x[j+1] = x[j]
  187.         else
  188.         final = j + 1
  189.         exit
  190.         end if
  191.     end for
  192.     x[final] = temp
  193.     end for
  194. end procedure
  195.  
  196. procedure best_sort(natural m, natural n)
  197. -- put x[m..n] into (roughly) ascending order
  198. -- using recursive quick sort 
  199.     natural last, midpt
  200.     object midval, temp
  201.  
  202.     if n - m < hybrid_limit then 
  203.     return
  204.     end if
  205.  
  206.     midpt = floor((m + n) / 2)
  207.     midval = x[midpt]
  208.     x[midpt] = x[m]
  209.  
  210.     last = m
  211.     for i = m+1 to n do
  212.     if compare(x[i], midval) < 0 then
  213.         last = last + 1
  214.         temp = x[last]  x[last] = x[i]  x[i] = temp
  215.     end if
  216.     end for
  217.     x[m] = x[last]
  218.     x[last] = midval
  219.     best_sort(m, last-1)
  220.     best_sort(last+1, n)
  221. end procedure
  222.  
  223. global function great_sort(sequence a)
  224. -- Avoids dynamic storage allocation - just passes indexes into
  225. -- a global sequence.
  226. -- Not much better than hybrid_sort which makes full use of dynamic
  227. -- storage allocation.
  228. -- Note that we only partition down to a certain degree, then do an
  229. -- insertion sort which runs fast because things are roughly in order.
  230. -- See Knuth for the details.
  231.     x = a
  232.     best_sort(1, length(x))
  233.     g_insertion_sort()
  234.     return x
  235. end function
  236.  
  237. global function merge_sort(sequence x)
  238. -- put x into ascending order
  239. -- using recursive merge sort
  240.     natural n, mid
  241.     sequence merged, a, b
  242.  
  243.     n = length(x)
  244.     if n < 2 then
  245.     return x
  246.     end if
  247.  
  248.     mid = floor(n/2)
  249.     a = merge_sort(x[1..mid])       -- sort the first half
  250.     b = merge_sort(x[mid+1..n])     -- sort the second half
  251.     
  252.     -- merge the two sorted halves into one
  253.     merged = {}
  254.     while length(a) > 0 and length(b) > 0 do
  255.     if compare(a[1], b[1]) < 0 then
  256.         merged = append(merged, a[1])
  257.         a = a[2..length(a)]
  258.     else
  259.         merged = append(merged, b[1])
  260.         b = b[2..length(b)]
  261.     end if
  262.     end while
  263.     return merged & a & b -- merged data plus leftovers
  264. end function
  265.  
  266. procedure check_results(sequence sdata, sequence data)
  267. -- compare results with another sort to make sure they are correct
  268.     if CHECK_RESULTS then
  269.     if compare(sdata, shell_sort(data)) != 0 then
  270.         puts(2, "\nabort!\n")
  271.         print(2, 1/0)
  272.     end if
  273.     end if
  274. end procedure
  275.  
  276. procedure all_sorts()
  277. -- test all sorting routines over a range of numbers of items
  278.  
  279.     file_number printer
  280.     natural nitems, iterations
  281.     atom t0, t
  282.     sequence data, sdata
  283.  
  284.     printer = 1   -- open("PRN", "w")
  285.     nitems = 5
  286.     while nitems <= MAX do
  287.     -- get several sets of data of length nitems
  288.     iterations = floor(MAX/nitems)
  289.     if iterations > 500 then
  290.         iterations = 500
  291.     end if
  292.     printf(printer, "\ntime (sec.) to sort %d items (averaged over %d trials)\n",
  293.             {nitems, iterations})
  294.  
  295.     data = rand(repeat(repeat(nitems, nitems), iterations))
  296.     t0 = time()
  297.     for i = 1 to iterations do
  298.         sdata = bubble_sort(data[i])
  299.         check_results(sdata, data[i])
  300.     end for
  301.     t = time() - t0
  302.     printf(printer, "bubble sort   %9.4f\n", t/iterations)
  303.  
  304.     t0 = time()
  305.     for i = 1 to iterations do
  306.         sdata =  simple_sort(data[i])
  307.         check_results(sdata, data[i])
  308.     end for
  309.     t = time() - t0
  310.     printf(printer, "simple sort   %9.4f\n", t/iterations)
  311.  
  312.     t0 = time()
  313.     for i = 1 to iterations do
  314.         sdata = insertion_sort(data[i])
  315.         check_results(sdata, data[i])
  316.     end for
  317.     t = time() - t0
  318.     printf(printer, "insertion sort%9.4f\n", t/iterations)
  319.  
  320.     t0 = time()
  321.     for i = 1 to iterations do
  322.         sdata = merge_sort(data[i])
  323.         check_results(sdata, data[i])
  324.     end for
  325.     t = time() - t0
  326.     printf(printer, "merge sort    %9.4f\n", t/iterations)
  327.  
  328.     t0 = time()
  329.     for i = 1 to iterations do
  330.         sdata = quick_sort(data[i])
  331.         check_results(sdata, data[i])
  332.     end for
  333.     t = time() - t0
  334.     printf(printer, "quick sort    %9.4f\n", t/iterations)
  335.  
  336.     for hl = 20 to 20 by 2 do
  337.         hybrid_limit = hl
  338.         t0 = time()
  339.         for i = 1 to iterations do
  340.         sdata = hybrid_sort(data[i])
  341.         check_results(sdata, data[i])
  342.         end for
  343.         t = time() - t0
  344.         printf(printer, "hybrid sort-%d%9.4f\n", {hybrid_limit,t/iterations})
  345.     end for
  346.  
  347.     for hl = 20 to 20 by 2 do
  348.         hybrid_limit = hl
  349.         t0 = time()
  350.         for i = 1 to iterations do
  351.         sdata = great_sort(data[i])
  352.         check_results(sdata, data[i])
  353.         end for
  354.         t = time() - t0
  355.         printf(printer, "great sort-%d %9.4f\n", {hybrid_limit,t/iterations})
  356.     end for
  357.  
  358.     t0 = time()
  359.     for i = 1 to iterations do
  360.         sdata = shell_sort(data[i])
  361.         check_results(sdata, data[i])
  362.     end for
  363.     t = time() - t0
  364.     printf(printer, "shell sort    %9.4f\n", t/iterations)
  365.  
  366.     puts(1, "\nPress Enter to continue, q to quit: ")
  367.     if find('q', gets(0)) then
  368.         abort(0)
  369.     end if
  370.     nitems = nitems * 2
  371.     end while
  372. end procedure
  373.  
  374. all_sorts()
  375.  
  376.